﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
//using NUnit.Framework.Constraints;
using NUnit.Framework.SyntaxHelpers;
using FileModelNS;

namespace FileModelTest
{
	[TestFixture]
	public class FileModelTest
	{
		[Test]
		public void testSelectedFormatNode_NoSelection()
		{
			FileModel fileModel = new FileModel();
			fileModel.LoadFile(@"..\..\TestResource\notepad.exe");
			fileModel.LoadFormatFile(@"..\..\TestResource\Windows PE Format.xml");

			Assert.AreEqual(null, fileModel.SelectedFormatNode);
		}

		[Test]
		public void testSelectFormatNode_WithPath()
		{
			FileModel fileModel = new FileModel();
			fileModel.LoadFile(@"..\..\TestResource\notepad.exe" );
			fileModel.LoadFormatFile(@"..\..\TestResource\Windows PE Format.xml");

			fileModel.SelectFormatNode( @"PE_FILE\IMAGE_DOS_HEADER\e_crlc" );
			Assert.AreEqual(@"PE_FILE\IMAGE_DOS_HEADER\e_crlc", fileModel.SelectedFormatNode.Path);
		}

		[Test]
		public void testSelectFormatNode_WithOffset()
		{
			FileModel fileModel = new FileModel();
			fileModel.LoadFile(@"..\..\TestResource\notepad.exe");
			fileModel.LoadFormatFile(@"..\..\TestResource\Windows PE Format.xml");

			fileModel.SelectFormatNode( 7 );
			var sfn = fileModel.SelectedFormatNode;
			Assert.AreEqual(@"PE_FILE\IMAGE_DOS_HEADER\e_crlc", sfn.Path);
			Assert.That(7, Is.GreaterThanOrEqualTo(sfn.Offset) & Is.LessThan( sfn.Offset + sfn.Size ));
		}

		[Test]
		[ExpectedException( typeof(Exception) )]
		public void testSelectFormatNode_WithOffset_OutOfRange()
		{
			FileModel fileModel = new FileModel();
			fileModel.LoadFile(@"..\..\TestResource\notepad.exe");
			fileModel.LoadFormatFile(@"..\..\TestResource\Windows PE Format.xml");

			fileModel.SelectFormatNode( fileModel.Data.Length );
		}

		[Test]
		public void testSelectFormatNode_WithOffset_NoResult()
		{
			FileModel fileModel = new FileModel();
			fileModel.LoadFile(@"..\..\TestResource\notepad.exe");
			fileModel.LoadFormatFile(@"..\..\TestResource\Windows PE Format.xml");

			// No Exception!
			fileModel.SelectFormatNode(fileModel.Data.Length - 1);
		}

		// TODO: Use Assert.Pass() when we upgrade to NUnit 2.5.
		[Test]
		[ExpectedException(typeof(Exception), ExpectedMessage = "MustPass")]
		public void testAutomaticUnloadingFileFormat()
		{
			FileModel fileModel = new FileModel();
			fileModel.LoadFile(@"..\..\TestResource\notepad.exe");
			fileModel.LoadFormatFile(@"..\..\TestResource\Windows PE Format.xml");

			fileModel.FormatUnloaded += (sender, e) =>
			{
				Assert.AreEqual(fileModel, sender);
				throw new Exception("MustPass");
			};

			fileModel.LoadFile(@"..\..\TestResource\notepad.exe");
		}

		[Test]
		[ExpectedException(typeof(Exception), ExpectedMessage = "MustPass")]
		public void testFileLoaded()
		{
			FileModel fileModel = new FileModel();
			fileModel.FileLoaded += (sender, e) =>
			{
				Assert.AreEqual(fileModel, sender);
				throw new Exception("MustPass");
			};

			fileModel.LoadFile(@"..\..\TestResource\notepad.exe");
		}

		[Test]
		[ExpectedException(typeof(Exception), ExpectedMessage = "MustPass")]
		public void testFormatLoaded()
		{
			FileModel fileModel = new FileModel();
			fileModel.FormatLoaded += (sender, e) =>
			{
				Assert.AreEqual(fileModel, sender);
				throw new Exception("MustPass");
			};

			fileModel.LoadFile(@"..\..\TestResource\notepad.exe");
			fileModel.LoadFormatFile(@"..\..\TestResource\Windows PE Format.xml");
		}

	}
}
